package com.learning.service.impl;

import com.learning.service.IAnalyzeService;
import com.learning.service.IAnswerPaperService;
import com.learning.service.IExamPaperService;
import com.learning.service.IQuestionService;
import com.learning.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class AnalyzeServiceImpl implements IAnalyzeService {

    @Autowired
    private IExamPaperService examPaperService;

    @Autowired
    private IAnswerPaperService answerPaperService;
    @Autowired
    private IQuestionService questionService;

    @Override
    public AnalyzeVO getAnalysis(Long paperId) {
        AnalyzeVO analyzeVO = new AnalyzeVO();
        analyzeVO.setPaperId(paperId);
        // 得到试卷信息
        ExamPaperVO examPaperVO = examPaperService.queryByExamPaperId(paperId);

        // 试卷难易程度
        analyzeVO.setWholeDifficulty(examPaperVO.getDifficulty().getValue());

        List<ExamPaperQuestionVO> questionList = examPaperVO.getExamPaperQuestionList();
        Set<String> weakKnowledge = new HashSet<>();

        List<QuestionAnalysisVo> qaList = new ArrayList<>();
        for (ExamPaperQuestionVO question : questionList) {
            QuestionAnalysisVo qa = new QuestionAnalysisVo();
            QuestionDetailVO queryDetail = questionService.queryDetail(qa.getQuestionId());
            qa.setQuestionId(question.getQuestionId());
            qa.setDifficulty(question.getDifficulty().getValue());
            qa.setKnowledge(question.getKnowledgeContent());
            qa.setType(question.getQuestionType().getValue());
            if (queryDetail == null){
                continue;
            }
            qa.setErrorRate(queryDetail.getErrorRate());

            if (queryDetail.getErrorRate() > 0.4) {
                weakKnowledge.add(queryDetail.getKnowledgeContent());
            }

            qaList.add(qa);
        }

        List<String> result = new ArrayList<>(weakKnowledge);

        analyzeVO.setQuestionAnalysisVos(qaList);
        analyzeVO.setClassScore(getClassScore());
        analyzeVO.setMaxScore(getMaxAndMinScore()[0]);
        analyzeVO.setMinScore(getMaxAndMinScore()[1]);
        analyzeVO.setWeakKnowledge(result);

        return analyzeVO;
    }

    private Double getClassScore() {
        // 得到试卷的结果
        List<AnswerPaperFinishedVO> paperResult = answerPaperService.getAnswerPapers();
        // 拿到分数转为Long类型
        List<Long> totalGradeToLong = paperResult.stream()
                .map(AnswerPaperFinishedVO::getTotalGrade)
                .filter(AnalyzeServiceImpl::isNumeric) // 过滤非数字字符串
                .map(Long::parseLong)
                .collect(Collectors.toList());        // 求平均值
        // 求平均值
        OptionalDouble average = totalGradeToLong.stream().mapToLong(Long::longValue).average();
        // 返回平均值，如果没有则返回默认值 0.0
        return average.orElse(0.0);
    }

    public Long[] getMaxAndMinScore() {
        Long[] result = new Long[2];
        // 得到试卷的结果
        List<AnswerPaperFinishedVO> paperResult = answerPaperService.getAnswerPapers();
        // 拿到分数
        List<String> totalGrade = paperResult.stream()
                .map(AnswerPaperFinishedVO::getTotalGrade)
                .collect(Collectors.toList());
        // 转为Long类型，过滤非数字字符串
        List<Long> totalGradeToLong = totalGrade.stream()
                .filter(AnalyzeServiceImpl::isNumeric)
                .map(Long::parseLong)
                .collect(Collectors.toList());

        // 取出最大的数
        Optional<Long> maxGrade = totalGradeToLong.stream().max(Long::compare);
        // 取出最小的数
        Optional<Long> minGrade = totalGradeToLong.stream().min(Long::compare);

        // 如果存在最大值和最小值则赋值，否则赋默认值（如0）
        result[0] = maxGrade.orElse(0L);
        result[1] = minGrade.orElse(0L);

        return result;
    }

    private static boolean isNumeric(String str) {
        if (str == null || str.isEmpty()) {
            return false;
        }
        try {
            Long.parseLong(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }
}
